package tushare

import (
	"bytes"
	"encoding/json"
	"fmt"
	"strconv"
	"strings"

	tmath "tushare/math"
	"tushare/model"
	"tushare/model/tushare"

	"io/ioutil"
	"net/http"

	"tushare/conf"

	"time"

	"math"

	"github.com/golang-module/carbon"
)

type requestRawDaily struct {
	ApiName string             `json:"api_name"`
	Token   string             `json:"token"`
	Fields  string             `json:"fields"`
	Params  requestParamsDaily `json:"params"`
}

type requestParamsDaily struct {
	TradeDate string `json:"trade_date"`
	TsCode    string `json:"ts_code"`
}

type resposeJsonDaily struct {
	RequestId string           `json:"request_id"`
	Code      int              `json:"code"`
	Data      resposeDataDaily `json:"data"`
}

type resposeDataDaily struct {
	Items [][]interface{} `json:"items"`
}

func Daily(trageDate string) {

	pullDaily(trageDate)

}

func FiveDayAvg() {
	stocks := model.StockList()
	for _, v := range stocks {
		avg := tushare.FiveDayAvg(v.TsCode)
		tushare.FiveDayAvgUpdate(v.TsCode, avg/5)
	}
}

func pullDaily(trade_date string) {
	rw := requestRawDaily{}
	rw.ApiName = "daily"
	rw.Token = conf.GetToken()
	rw.Fields = "ts_code,trade_date,open,high,low,close,pre_close,change,pct_chg,vol,amount"
	rw.Params.TradeDate = trade_date

	bytesData, _ := json.Marshal(rw)

	resp, _ := http.Post("http://api.waditu.com", "application/json", bytes.NewReader(bytesData))
	body, _ := ioutil.ReadAll(resp.Body)

	jsonStrByte := []byte(body)
	decodeData := resposeJsonDaily{}
	json.Unmarshal(jsonStrByte, &decodeData)

	// var buffer bytes.Buffer
	// lenItem := len(decodeData.Data.Items)
	// sql := "INSERT INTO `tushare_daily` (`ts_code`,trade_date,open,high,low,close,pre_close,change,pct_chg,vol,amount) values"
	for _, v := range decodeData.Data.Items {
		d := tushare.Daily{}
		d.TsCode = v[0].(string)
		d.TradeDate = v[1].(string)
		d.Open = interfaceNilToZero(v[2])
		d.High = interfaceNilToZero(v[3])
		d.Low = interfaceNilToZero(v[4])
		d.Close = interfaceNilToZero(v[5])
		d.PreClose = interfaceNilToZero(v[6])
		d.Change = interfaceNilToZero(v[7])
		d.PctChg = interfaceNilToZero(v[8])
		d.Vol = interfaceNilToZero(v[9])
		d.Amount = interfaceNilToZero(v[10])

		dailyInfo := tushare.DailyExist(d.TsCode, d.TradeDate)
		if dailyInfo.TsCode != "" {
			continue
		}

		tushare.DailyCreate(d)
		// if _, err := buffer.WriteString(sql); err != nil {
		// 	fmt.Println(err)
		// }
		// if lenItem-1 == i {
		// 	buffer.WriteString(fmt.Sprintf("('%s','%s','%f','%f','%f','%f','%f','%f','%f','%f','%f')", d.TsCode, d.TradeDate, d.Open, d.High, d.Low, d.Close, d.PreClose, d.Change, d.PctChg, d.Vol, d.Amount))
		// 	continue
		// }
		// buffer.WriteString(fmt.Sprintf("('%s','%s','%f','%f','%f','%f','%f','%f','%f','%f','%f'),", d.TsCode, d.TradeDate, d.Open, d.High, d.Low, d.Close, d.PreClose, d.Change, d.PctChg, d.Vol, d.Amount))
	}
	//tushare.DailyBatchCreate(buffer.String())
}

//近期低位
func RecentLowAmont() {
	stocks := model.StockList()
	for _, v := range stocks {
		first_low := tushare.RecentLowAmont(v.TsCode, "20211008", "20211027")
		second_low := tushare.RecentLowAmont(v.TsCode, "20210907", "20211027")
		rs := tushare.ReferenceSubstance{}
		rs.TsCode = v.TsCode
		rs.FirstLow = first_low
		rs.SecondLow = second_low

		tushare.ReferenceSubstanceCreate(rs)
	}

}

func BackFive(tradeDate string) {
	data := tushare.BackFiveDayAvg(tradeDate)
	for _, v := range data {
		bf := tushare.BackFive{}
		bf.TsCode = v.TsCode
		bf.Name = v.Name
		bf.TradeDate = v.TradeDate
		bf.FiveAmount = v.FiveDayAvg
		bf.Close = v.Close
		bf.Vol = v.Vol
		bf.Amount = v.Amount
		tushare.BackFiveCreate(bf)
	}
}

func Angle(tradeDate, avgDay string) {
	stocks := model.StockList()
	for _, v := range stocks {
		nowDate := tradeDate
		subDay := carbon.Parse(nowDate).SubDay().ToDateString()

		nowDateTime, _ := time.Parse("2006-01-02", nowDate)
		nowDate = nowDateTime.Format("20060102")

		subDayTime, _ := time.Parse("2006-01-02", subDay)
		subDay = subDayTime.Format("20060102")

		price1 := tushare.AvgLine(v.TsCode, nowDate, avgDay)
		price2 := tushare.AvgLine(v.TsCode, subDay, avgDay)

		//均线角度 ATAN((五日线/昨日五线-1)*100)*180/3.1416
		ar := math.Atan((price1/price2-1)*100) * 180 / 3.141529
		close := tushare.CloseByTradeDate(v.TsCode, nowDate)

		angle := tushare.Angle{}
		angle.TsCode = v.TsCode
		angle.Name = v.Name
		angle.TradeDate = nowDate
		angle.Close = close
		angle.AvgAmount = price1
		avgDayInt, _ := strconv.ParseInt(avgDay, 10, 64)
		angle.AvgType = avgDayInt
		angle.Angle, _ = strconv.ParseFloat(fmt.Sprintf("%.6f", ar), 64)
		tushare.AngleCreate(angle)
	}

}

/**
当日实时角度
avgDay 均线类型 5,10,15,20
**/
func ImAngle() {
	stocks := model.StockList()
	for {
		for _, v := range stocks {
			avgLineClose := tushare.AvgLineByDay(v.TsCode, 4)
			totalSumClose := v.Close + avgLineClose
			avgClose := totalSumClose / 5

			avgLineClose1 := tushare.AvgLineByDay(v.TsCode, 5)
			avgClose1 := avgLineClose1 / 5

			//均线角度 ATAN((五日线/昨日五线-1)*100)*180/3.1416
			ar := math.Atan((avgClose/avgClose1-1)*100) * 180 / 3.141529

			na := tushare.NowAngle{}
			na.TsCode = v.TsCode
			na.Angle, _ = strconv.ParseFloat(fmt.Sprintf("%.6f", ar), 64)
			na.ImAmount = v.ImAmount
			if math.IsNaN(na.Angle) {
				continue
			}

			info := tushare.NowAngleByTsCode(v.TsCode)
			if info.Id == 0 {
				tushare.NowAngleCreate(na)
			} else {
				info.Angle = na.Angle
				info.ImAmount = na.ImAmount
				tushare.NowAngleUpdate(info)
			}

		}
	}
}

func MagicalNine(magicalNum, typeNum int64, startDate string) {
	var nowDate string

	stocks := model.StockList()
	var sum int64
	for _, v := range stocks {
		nowDate = startDate
		sum = 0
		var i int64
		for i = 1; i <= magicalNum; i++ {
			//获取前一天时间
			subDay := carbon.Parse(nowDate).SubDay().ToDateString()
			nowDate = subDay
			nowDateTime, _ := time.Parse("2006-01-02", subDay)
			subDayPare := nowDateTime.Format("20060102")

			daily := tushare.GetRowsByLimt(5, v.TsCode, subDayPare)
			if daily[0].Close > 15 {
				continue
			}
			if daily[0].Amount < 100000 && daily[1].Amount < 100000 {
				continue
			}
			if typeNum == 0 {
				if daily[0].Close > daily[4].Close {
					//fmt.Printf("%f %f\n", daily[0].Close, daily[4].Close)
					sum += 1
				}
			}
			if typeNum == 1 {
				if daily[0].Close < daily[4].Close {
					//fmt.Printf("%f %f\n", daily[0].Close, daily[4].Close)
					sum += 1
				}
			}

		}

		if sum == magicalNum {
			mn := tushare.MagicalNine{}
			mn.TsCode = v.TsCode
			mn.Continuous = sum
			mn.Type = typeNum
			mn.CreateDate = startDate

			tushare.MagicalNineCreate(mn)
		}
	}

}

//阳夹阴
func RedClampGreen() {
	stocks := model.StockList()
	for _, v := range stocks {
		daily := tushare.RaisingLimitDays(5, v.TsCode)
		if len(daily) < 3 {
			continue
		}
		if daily[0].PctChg < 0 || daily[1].PctChg > 0 || daily[2].PctChg < 0 {
			continue
		}
		if daily[0].Amount < 100000 || daily[1].Amount < 100000 || daily[2].Amount < 100000 {
			continue
		}
		if daily[0].Close < daily[4].Close {
			continue
		}
		if daily[0].Close > 22 {
			continue
		}

		fmt.Println(v.TsCode)
	}
}

func DailyMinByLimit(limit int64) {
	stocks := model.StockList()
	for _, v := range stocks {
		min := tushare.GetDailyMinByLimit(v.TsCode, limit)
		if v.Close-min.Min > 0.1 {
			continue
		}
		dm := tushare.DailyMin{}
		dm.LimitDays = limit
		dm.Min = min.Min
		dm.TsCode = v.TsCode
		dm.CreateDate = carbon.Now().ToDateString()
		tushare.DailyMinCreate(dm)
	}
}

//当日超跌
func OpenDay() {
	stocks := model.StockList()
	for {
		for _, v := range stocks {
			if v.Close > 20 {
				continue
			}
			dailyRows := tushare.DailyRowsByLimt(6, v.TsCode)
			if len(dailyRows) < 6 {
				continue
			}
			if dailyRows[0].PctChg > 0 && dailyRows[1].PctChg > 0 && dailyRows[2].PctChg < 0 && dailyRows[3].PctChg < 0 && dailyRows[4].PctChg < 0 {

			} else {
				continue
			}

			line := new(Line)
			arr := strings.Split(v.TsCode, ".")
			m := line.MinuteLine(fmt.Sprintf("%s%s", arr[1], arr[0]))

			for k, vi := range m.Data.Items {
				if vi.Percent < -5 {
					od := tushare.OpenDay{}
					od.TsCode = v.TsCode
					od.Percent = m.Data.Items[k].Percent
					od.CreateTime = carbon.Now().ToDateTimeString()
					tushare.OpenDayCreate(od)
				}
			}
		}
	}
}

func DailyLineAngle() {
	//ar := math.Atan((avgClose/avgClose1-1)*100) * 180 / 3.141529
	stocks := model.StockList()
	for _, v := range stocks {
		dailyRows := tushare.DailyRowsByLimt(30, v.TsCode)
		if len(dailyRows) < 30 {
			continue
		}
		ar := tmath.LineAngle(dailyRows[0].Close, dailyRows[29].Close)
		if ar >= 40 && ar <= 47 {
			fmt.Println(v.TsCode)
		}
	}

}

func DailyCheck() {
	stocks := model.StockList()
	for _, v := range stocks {
		rw := requestRawDaily{}
		rw.ApiName = "daily"
		rw.Token = conf.GetToken()
		rw.Fields = "ts_code,trade_date,open,high,low,close,pre_close,change,pct_chg,vol,amount"
		rw.Params.TsCode = v.TsCode

		bytesData, _ := json.Marshal(rw)

		resp, _ := http.Post("http://api.waditu.com", "application/json", bytes.NewReader(bytesData))
		body, _ := ioutil.ReadAll(resp.Body)

		jsonStrByte := []byte(body)
		decodeData := resposeJsonDaily{}
		json.Unmarshal(jsonStrByte, &decodeData)

		for _, v := range decodeData.Data.Items {
			d := tushare.Daily{}
			d.TsCode = v[0].(string)
			d.TradeDate = v[1].(string)
			d.Open = interfaceNilToZero(v[2])
			d.High = interfaceNilToZero(v[3])
			d.Low = interfaceNilToZero(v[4])
			d.Close = interfaceNilToZero(v[5])
			d.PreClose = interfaceNilToZero(v[6])
			d.Change = interfaceNilToZero(v[7])
			d.PctChg = interfaceNilToZero(v[8])
			d.Vol = interfaceNilToZero(v[9])
			d.Amount = interfaceNilToZero(v[10])

			dailyInfo := tushare.DailyExist(d.TsCode, d.TradeDate)
			if dailyInfo.TsCode != "" {
				continue
			}

			tushare.DailyCreate(d)
		}
	}

}

func DailyAvgLineTop() {
	stocks := model.StockList()
	for _, v := range stocks {
		if v.Close > 20 {
			continue
		}

		if !dailyAvgLine(v, 0) {
			continue
		}
		if !dailyAvgLine(v, 1) {
			continue
		}
		if !dailyAvgLine(v, 2) {
			continue
		}
		if !dailyAvgLine(v, 3) {
			continue
		}
		if !dailyAvgLine(v, 4) {
			continue
		}
		fmt.Println(v.TsCode)
	}
}

func dailyAvgLine(v model.TushareStock, l int64) bool {
	fiveSum := tushare.DailySumByLimit(v.TsCode, 5, l)
	tenSum := tushare.DailySumByLimit(v.TsCode, 10, l)
	twentySum := tushare.DailySumByLimit(v.TsCode, 20, l)
	thirtySum := tushare.DailySumByLimit(v.TsCode, 30, l)

	fiveAvg := fiveSum / 5
	tenAvg := tenSum / 10
	twentyAvg := twentySum / 20
	thirtyAvg := thirtySum / 30

	if v.Close-fiveAvg < -0.1 || v.Close-tenAvg < -0.1 || v.Close-twentyAvg < -0.1 || v.Close-thirtyAvg < -0.1 {
		return false
	}
	return true
}

//金针
func DailyGoldNeedle() {
	line := new(Line)
	stocks := model.StockList()
	for _, v := range stocks {
		if v.Close > 20 {
			continue
		}
		tsCodeArr := strings.Split(v.TsCode, ".")
		data := line.MinuteLine(fmt.Sprintf("%s%s", tsCodeArr[1], tsCodeArr[0]))
		i := 0
		for _, item := range data.Data.Items {
			if i > 0 {
				break
			}
			if item.Percent < -4 && data.Data.Items[data.Data.ItemsSize-1].Percent > 1 {
				i += 1
				fmt.Println(v.TsCode)
			}
		}
	}

}

//阳夹阴
func DailyYjy() {
	stocks := model.StockList()
	for _, v := range stocks {
		if v.Close > 20 {
			continue
		}

		dailyList := tushare.DailyRowsByLimt(5, v.TsCode)
		if len(dailyList) < 5 {
			continue
		}

		if dailyList[0].Close-dailyList[0].Open > 0 {
			continue
		}

		if dailyList[1].Close-dailyList[1].Open < 0 {
			continue
		}

		if dailyList[2].Close-dailyList[2].Open > 0 {
			continue
		}

		fiveSum := tushare.DailySumByLimit(v.TsCode, 5, 1)
		tenSum := tushare.DailySumByLimit(v.TsCode, 10, 1)
		twentySum := tushare.DailySumByLimit(v.TsCode, 20, 1)

		fiveAvg := fiveSum / 5
		tenAvg := tenSum / 10
		twentyAvg := twentySum / 20

		if dailyList[1].Close < fiveAvg {
			continue
		}

		if dailyList[1].Close-tenAvg < -0.1 {
			continue
		}

		if dailyList[1].Close-twentyAvg < -0.1 {
			continue
		}

		fmt.Println(v.TsCode)
	}
}

//阳夹三阴
func DailyYthreey() {
	stocks := model.StockList()
	for _, v := range stocks {
		if v.Close > 12 || v.Close < 3 {
			continue
		}

		dailyList := tushare.DailyRowsByLimt(5, v.TsCode)
		if len(dailyList) < 5 {
			continue
		}

		if dailyList[0].PctChg <= 0 {
			continue
		}

		if dailyList[1].PctChg >= 0 {
			continue
		}

		if dailyList[2].PctChg >= 0 {
			continue
		}

		if dailyList[3].PctChg >= 0 {
			continue
		}

		if dailyList[4].PctChg <= 0 {
			continue
		}

		if dailyList[0].Close-dailyList[0].Open <= 0 {
			continue
		}

		if dailyList[1].Close-dailyList[1].Open >= 0 {
			continue
		}

		if dailyList[2].Close-dailyList[2].Open >= 0 {
			continue
		}

		if dailyList[3].Close-dailyList[3].Open >= 0 {
			continue
		}

		if dailyList[4].Close-dailyList[4].Open <= 0 {
			continue
		}

		fmt.Println(v.TsCode)

	}
}

//连续跌
func DailyDownFour() {
	stocks := model.StockList()
	for _, v := range stocks {
		if v.Close > 20 {
			continue
		}

		// dailyList := tushare.DailyRowsByLimt(4, v.TsCode)
		// if len(dailyList) < 4 {
		// 	continue
		// }

		sixty := tushare.DailySumByLimit(v.TsCode, 145, 0) / 145

		if v.Close-sixty > 0.1 || v.Close-sixty <= 0 {
			continue
		}

		t := fmt.Sprintf("%s %f %f", v.TsCode, v.Close, sixty)
		fmt.Println(t)

	}
}

func MinuteDay() {
	stocks := model.StockList()
	for _, v := range stocks {
		l := new(Line)
		tsCodeArr := strings.Split(v.TsCode, ".")
		data := l.MinuteLine(tsCodeArr[1] + tsCodeArr[0])
		b, _ := json.Marshal(data)
		m := tushare.Minute{}
		m.MinuteJson = string(b)
		m.TsCode = v.TsCode
		m.CreateDate = carbon.Now().ToDateString()
		tushare.MinuteCreate(m)
	}
}
